/**
@description: the implemetaion of circular buffer
@author: timlentse(tinglenxan@hotmail.com)
@class name: circularBuffer
@constructor argument: --n(sizeof the circularbuffer)
@Date: 2014-11-01
*/
#include <iostream>
#include <string>
#include <sstream>
#include <cstring>
#include <stdlib.h>

using namespace std;

class circularBuffer {
public:
	circularBuffer( int n ) : _Size( n ), begin( 0 ), count( 0 )
	{
		this->element = (char * *) malloc( sizeof(this->element) * n );
	}


private:
	int	_Size, begin, count;
	char	** element;
public:
	void addElement( string data );


	void removElements( int n );


	void getAllElements();


	~circularBuffer()
	{
	}
};

void circularBuffer::addElement( string data )
{
	static int	index	= 0;
	char		* tmp	= new char[data.length() + 1];
	strcpy( tmp, data.c_str() );
	this->element[index]	= tmp;
	++index			%= this->_Size;
	if ( this->count == this->_Size )
	{
		this->count	= this->count;
		++this->begin	%= this->_Size;
	} else {
		++this->count;
	}
	return;
}


void circularBuffer::removElements( int n )
{
	int i = 0;
	while ( (i < n) && (this->count) )
	{
		/* FIFO implementation */
		++this->begin;
		this->begin %= this->_Size;
		--this->count;
		++i;
	}

	return;
}


void circularBuffer::getAllElements()
{
	int index = this->begin;
	for ( int i = 0; i < this->count; ++i )
	{
		cout << this->element[index] << endl;
		++index;
		index %= this->_Size;
	}
	return;
}


int main() {
	int	size = 0;
	string	inputbuf;
	char	command;

	/* Now get a number as the size of circular buffer. */
	while ( true )
	{
		getline( cin, inputbuf );
		/* This code converts from string to number safely. */
		stringstream mystream( inputbuf );
		if ( mystream >> size )
			break;
		cout << "Invalid number, please try again" << endl;
	}
	/* create a buffer class */
	circularBuffer	cirBuff( size );
	bool		flag		= true;
	int		numToBeAdded	= 0;
	int		numToBeDeleted	= 0;

	while ( true )
	{
		/* get input from cin */
		getline( cin, inputbuf );
		if ( flag )
		{
			command = inputbuf[0];
			switch ( command )
			{
			case 'A':
				if ( numToBeAdded = inputbuf[2] - 48 )
				{
					flag = false;
					break;
				} else {
					cout << "Error:unknow command, please try again!" << endl;
					break;
				}
			case 'R':
				if ( numToBeDeleted = inputbuf[2] - 48 )
				{
					cirBuff.removElements( numToBeDeleted );
					break;
				} else {
					cout << "Error:unknow command, please try again" << endl;
					break;
				}
			case 'L':
				cirBuff.getAllElements();
				break;
			case 'Q':
				return(0);
		    default :
				    cout << "Error:unknow command, please try again" << endl;
				    break;
			}
		}else {
			if ( numToBeAdded-- )
			{
				cirBuff.addElement( inputbuf );
				flag = (numToBeAdded == 0) ? true : false;
			}
		}
	}
	return(0);
}


